use sea_orm::ActiveValue::Set;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use validator::Validate;
use crate::entity::cfg_varsystem;

use crate::entity::cfg_varsystem::Model;
use crate::util::str_util::to_table_name;

#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct BasePointDto {
    pub id: i32,
    pub name: Option<String>,
    pub originName: Option<String>,
    pub kksCode: Option<String>,
    pub ioMapName: Option<String>,
    pub ioMapDirection: Option<i32>,
    pub dataType: Option<String>,
    pub description: Option<String>,
    pub defaultValue: Option<String>,
    pub forceValue: Option<String>,
    pub isHistory: Option<i8>,
    pub minimumScale: Option<String>,
    pub maximunScale: Option<String>,
    pub lowAlarm1Priority: Option<i32>,
    pub lowAlarm2Priority: Option<i32>,
    pub lowAlarm3Priority: Option<i32>,
    pub lowAlarm4Priority: Option<i32>,
    pub lowAlarmUserPriority: Option<i32>,
    pub highAlarm1Priority: Option<i32>,
    pub highAlarm2Priority: Option<i32>,
    pub highAlarm3Priority: Option<i32>,
    pub highAlarm4Priority: Option<i32>,
    pub highAlarmUserPriority: Option<i32>,
    pub lowAlarmLimit1Value: Option<f64>,
    pub lowAlarmLimit2Value: Option<f64>,
    pub lowAlarmLimit3Value: Option<f64>,
    pub lowAlarmLimit4Value: Option<f64>,
    pub lowAlarmLimitUserValue: Option<i32>,
    pub highAlarmLimit1Value: Option<f64>,
    pub highAlarmLimit2Value: Option<f64>,
    pub highAlarmLimit3Value: Option<f64>,
    pub highAlarmLimit4Value: Option<f64>,
    pub highAlarmLimitUserValue: Option<i32>,
    pub alarmPriority: Option<i32>,
    pub statusChecking: Option<i32>,
    pub isSoe: Option<i8>,
    pub ioType: Option<i32>,
    pub unit: Option<String>,
    pub prjControllerId: Option<i32>,
    pub opcAddress: Option<String>,
    pub prjSystemId: Option<i32>,
    pub source: Option<i32>,
    pub lowAlarmLimit1ValueEdit: Option<f64>,
    pub lowAlarmLimit2ValueEdit: Option<f64>,
    pub lowAlarmLimit3ValueEdit: Option<f64>,
    pub lowAlarmLimit4ValueEdit: Option<f64>,
    pub highAlarmLimit1ValueEdit: Option<f64>,
    pub highAlarmLimit2ValueEdit: Option<f64>,
    pub highAlarmLimit3ValueEdit: Option<f64>,
    pub highAlarmLimit4ValueEdit: Option<f64>,
    pub minimumScaleEdit: Option<f64>,
    pub maximunScaleEdit: Option<f64>,
    // pub test: Option<String>,
    // pub test2: Option<String>,
    // pub test3: Option<String>,
}


#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct PointDto {
    #[serde(flatten)]
    pub base: BasePointDto,
}

impl Into<Model> for PointDto {
    fn into(self) -> Model {
        Model {
            id: self.base.id,
            name: Some(self.base.originName.clone().unwrap()),
            kks_code: self.base.kksCode,
            io_map_name: self.base.ioMapName,
            io_map_direction: self.base.ioMapDirection,
            data_type: self.base.dataType,
            description: self.base.description,
            default_value: self.base.defaultValue,
            force_value: self.base.forceValue,
            is_history: self.base.isHistory,
            minimum_scale: self.base.minimumScale,
            maximun_scale: self.base.maximunScale,
            low_alarm1_priority: self.base.lowAlarm1Priority,
            low_alarm2_priority: self.base.lowAlarm2Priority,
            low_alarm3_priority: self.base.lowAlarm3Priority,
            low_alarm4_priority: self.base.lowAlarm4Priority,
            low_alarm_user_priority: self.base.lowAlarmUserPriority,
            high_alarm1_priority: self.base.highAlarm1Priority,
            high_alarm2_priority: self.base.highAlarm2Priority,
            high_alarm3_priority: self.base.highAlarm3Priority,
            high_alarm4_priority: self.base.highAlarm4Priority,
            high_alarm_user_priority: self.base.highAlarmUserPriority,
            low_alarm_limit1_value: self.base.lowAlarmLimit1Value,
            low_alarm_limit2_value: self.base.lowAlarmLimit2Value,
            low_alarm_limit3_value: self.base.lowAlarmLimit3Value,
            low_alarm_limit4_value: self.base.lowAlarmLimit4Value,
            low_alarm_limit_user_value: self.base.lowAlarmLimitUserValue,
            high_alarm_limit1_value: self.base.highAlarmLimit1Value,
            high_alarm_limit2_value: self.base.highAlarmLimit2Value,
            high_alarm_limit3_value: self.base.highAlarmLimit3Value,
            high_alarm_limit4_value: self.base.highAlarmLimit4Value,
            high_alarm_limit_user_value: self.base.highAlarmLimitUserValue,
            alarm_priority: self.base.alarmPriority,
            status_checking: self.base.statusChecking,
            is_soe: self.base.isSoe,
            io_type: self.base.ioType,
            unit: self.base.unit,
            prj_controller_id: self.base.prjControllerId,
            opc_address: self.base.opcAddress,
            prj_system_id: self.base.prjSystemId,
            source: self.base.source,
            low_alarm_limit1_value_edit: self.base.lowAlarmLimit1ValueEdit,
            low_alarm_limit2_value_edit: self.base.lowAlarmLimit2ValueEdit,
            low_alarm_limit3_value_edit: self.base.lowAlarmLimit3ValueEdit,
            low_alarm_limit4_value_edit: self.base.lowAlarmLimit4ValueEdit,
            high_alarm_limit1_value_edit: self.base.highAlarmLimit1ValueEdit,
            high_alarm_limit2_value_edit: self.base.highAlarmLimit2ValueEdit,
            high_alarm_limit3_value_edit: self.base.highAlarmLimit3ValueEdit,
            high_alarm_limit4_value_edit: self.base.highAlarmLimit4ValueEdit,
            minimum_scale_edit: self.base.minimumScaleEdit,
            maximun_scale_edit: self.base.maximunScaleEdit,
        }
    }
}

impl From<Model> for PointDto {
    fn from(model: Model) -> Self {
        PointDto{
            base: BasePointDto {
                id: model.id,
                name: Some(to_table_name(model.name.clone().unwrap())),
                originName: model.name,
                kksCode: model.kks_code,
                ioMapName: model.io_map_name,
                ioMapDirection: model.io_map_direction,
                dataType: model.data_type,
                description: model.description,
                defaultValue: model.default_value,
                forceValue: model.force_value,
                isHistory: model.is_history,
                minimumScale: model.minimum_scale,
                maximunScale: model.maximun_scale,
                lowAlarm1Priority: model.low_alarm1_priority,
                lowAlarm2Priority: model.low_alarm2_priority,
                lowAlarm3Priority: model.low_alarm3_priority,
                lowAlarm4Priority: model.low_alarm4_priority,
                lowAlarmUserPriority: model.low_alarm_user_priority,
                highAlarm1Priority: model.high_alarm1_priority,
                highAlarm2Priority: model.high_alarm2_priority,
                highAlarm3Priority: model.high_alarm3_priority,
                highAlarm4Priority: model.high_alarm4_priority,
                highAlarmUserPriority: model.high_alarm_user_priority,
                lowAlarmLimit1Value: model.low_alarm_limit1_value,
                lowAlarmLimit2Value: model.low_alarm_limit2_value,
                lowAlarmLimit3Value: model.low_alarm_limit3_value,
                lowAlarmLimit4Value: model.low_alarm_limit4_value,
                lowAlarmLimitUserValue: model.low_alarm_limit_user_value,
                highAlarmLimit1Value: model.high_alarm_limit1_value,
                highAlarmLimit2Value: model.high_alarm_limit2_value,
                highAlarmLimit3Value: model.high_alarm_limit3_value,
                highAlarmLimit4Value: model.high_alarm_limit4_value,
                highAlarmLimitUserValue: model.high_alarm_limit_user_value,
                alarmPriority: model.alarm_priority,
                statusChecking: model.status_checking,
                isSoe: model.is_soe,
                ioType: model.io_type,
                unit: model.unit,
                prjControllerId: model.prj_controller_id,
                opcAddress: model.opc_address,
                prjSystemId: model.prj_system_id,
                source: model.source,
                lowAlarmLimit1ValueEdit: model.low_alarm_limit1_value_edit,
                lowAlarmLimit2ValueEdit: model.low_alarm_limit2_value_edit,
                lowAlarmLimit3ValueEdit: model.low_alarm_limit3_value_edit,
                lowAlarmLimit4ValueEdit: model.low_alarm_limit4_value_edit,
                highAlarmLimit1ValueEdit: model.high_alarm_limit1_value_edit,
                highAlarmLimit2ValueEdit: model.high_alarm_limit2_value_edit,
                highAlarmLimit3ValueEdit: model.high_alarm_limit3_value_edit,
                highAlarmLimit4ValueEdit: model.high_alarm_limit4_value_edit,
                minimumScaleEdit: model.minimum_scale_edit,
                maximunScaleEdit: model.maximun_scale_edit,
                // test: model.test,
                // test2: model.test2,
                // test3: model.test3,
            },
        }
    }
}


impl PointDto {
    pub fn to_model_update(self, mut update_entity: cfg_varsystem::ActiveModel) -> cfg_varsystem::ActiveModel {
        if self.base.name.is_some() { update_entity.name = Set(self.base.name.clone()); }
        if self.base.kksCode.is_some() { update_entity.kks_code = Set(self.base.kksCode.clone()); }
        if self.base.ioMapName.is_some() { update_entity.io_map_name = Set(self.base.ioMapName.clone()); }
        if self.base.ioMapDirection.is_some() { update_entity.io_map_direction = Set(self.base.ioMapDirection.clone()); }
        if self.base.dataType.is_some() { update_entity.data_type = Set(self.base.dataType.clone()); }
        if self.base.description.is_some() { update_entity.description = Set(self.base.description.clone()); }
        if self.base.defaultValue.is_some() { update_entity.default_value = Set(self.base.defaultValue.clone()); }
        if self.base.forceValue.is_some() { update_entity.force_value = Set(self.base.forceValue.clone()); }
        if self.base.isHistory.is_some() { update_entity.is_history = Set(self.base.isHistory.clone()); }
        if self.base.minimumScale.is_some() { update_entity.minimum_scale = Set(self.base.minimumScale.clone()); }
        if self.base.maximunScale.is_some() { update_entity.maximun_scale = Set(self.base.maximunScale.clone()); }
        if self.base.lowAlarm1Priority.is_some() { update_entity.low_alarm1_priority = Set(self.base.lowAlarm1Priority.clone()); }
        if self.base.lowAlarm2Priority.is_some() { update_entity.low_alarm2_priority = Set(self.base.lowAlarm2Priority.clone()); }
        if self.base.lowAlarm3Priority.is_some() { update_entity.low_alarm3_priority = Set(self.base.lowAlarm3Priority.clone()); }
        if self.base.lowAlarm4Priority.is_some() { update_entity.low_alarm4_priority = Set(self.base.lowAlarm4Priority.clone()); }
        if self.base.lowAlarmUserPriority.is_some() { update_entity.low_alarm_user_priority = Set(self.base.lowAlarmUserPriority.clone()); }
        if self.base.highAlarm1Priority.is_some() { update_entity.high_alarm1_priority = Set(self.base.highAlarm1Priority.clone()); }
        if self.base.highAlarm2Priority.is_some() { update_entity.high_alarm2_priority = Set(self.base.highAlarm2Priority.clone()); }
        if self.base.highAlarm3Priority.is_some() { update_entity.high_alarm3_priority = Set(self.base.highAlarm3Priority.clone()); }
        if self.base.highAlarm4Priority.is_some() { update_entity.high_alarm4_priority = Set(self.base.highAlarm4Priority.clone()); }
        if self.base.highAlarmUserPriority.is_some() { update_entity.high_alarm_user_priority = Set(self.base.highAlarmUserPriority.clone()); }
        if self.base.lowAlarmLimit1Value.is_some() { update_entity.low_alarm_limit1_value = Set(self.base.lowAlarmLimit1Value.clone()); }
        if self.base.lowAlarmLimit2Value.is_some() { update_entity.low_alarm_limit2_value = Set(self.base.lowAlarmLimit2Value.clone()); }
        if self.base.lowAlarmLimit3Value.is_some() { update_entity.low_alarm_limit3_value = Set(self.base.lowAlarmLimit3Value.clone()); }
        if self.base.lowAlarmLimit4Value.is_some() { update_entity.low_alarm_limit4_value = Set(self.base.lowAlarmLimit4Value.clone()); }
        if self.base.lowAlarmLimitUserValue.is_some() { update_entity.low_alarm_limit_user_value = Set(self.base.lowAlarmLimitUserValue.clone()); }
        if self.base.highAlarmLimit1Value.is_some() { update_entity.high_alarm_limit1_value = Set(self.base.highAlarmLimit1Value.clone()); }
        if self.base.highAlarmLimit2Value.is_some() { update_entity.high_alarm_limit2_value = Set(self.base.highAlarmLimit2Value.clone()); }
        if self.base.highAlarmLimit3Value.is_some() { update_entity.high_alarm_limit3_value = Set(self.base.highAlarmLimit3Value.clone()); }
        if self.base.highAlarmLimit4Value.is_some() { update_entity.high_alarm_limit4_value = Set(self.base.highAlarmLimit4Value.clone()); }
        if self.base.highAlarmLimitUserValue.is_some() { update_entity.high_alarm_limit_user_value = Set(self.base.highAlarmLimitUserValue.clone()); }
        if self.base.alarmPriority.is_some() { update_entity.alarm_priority = Set(self.base.alarmPriority.clone()); }
        if self.base.statusChecking.is_some() { update_entity.status_checking = Set(self.base.statusChecking.clone()); }
        if self.base.isSoe.is_some() { update_entity.is_soe = Set(self.base.isSoe.clone()); }
        if self.base.ioType.is_some() { update_entity.io_type = Set(self.base.ioType.clone()); }
        if self.base.unit.is_some() { update_entity.unit = Set(self.base.unit.clone()); }
        if self.base.prjControllerId.is_some() { update_entity.prj_controller_id = Set(self.base.prjControllerId.clone()); }
        if self.base.opcAddress.is_some() { update_entity.opc_address = Set(self.base.opcAddress.clone()); }
        if self.base.prjSystemId.is_some() { update_entity.prj_system_id = Set(self.base.prjSystemId.clone()); }
        if self.base.source.is_some() { update_entity.source = Set(self.base.source.clone()); }
        if self.base.lowAlarmLimit1ValueEdit.is_some() { update_entity.low_alarm_limit1_value_edit = Set(self.base.lowAlarmLimit1ValueEdit.clone()); }
        if self.base.lowAlarmLimit2ValueEdit.is_some() { update_entity.low_alarm_limit2_value_edit = Set(self.base.lowAlarmLimit2ValueEdit.clone()); }
        if self.base.lowAlarmLimit3ValueEdit.is_some() { update_entity.low_alarm_limit3_value_edit = Set(self.base.lowAlarmLimit3ValueEdit.clone()); }
        if self.base.lowAlarmLimit4ValueEdit.is_some() { update_entity.low_alarm_limit4_value_edit = Set(self.base.lowAlarmLimit4ValueEdit.clone()); }
        if self.base.highAlarmLimit1ValueEdit.is_some() { update_entity.high_alarm_limit1_value_edit = Set(self.base.highAlarmLimit1ValueEdit.clone()); }
        if self.base.highAlarmLimit2ValueEdit.is_some() { update_entity.high_alarm_limit2_value_edit = Set(self.base.highAlarmLimit2ValueEdit.clone()); }
        if self.base.highAlarmLimit3ValueEdit.is_some() { update_entity.high_alarm_limit3_value_edit = Set(self.base.highAlarmLimit3ValueEdit.clone()); }
        if self.base.highAlarmLimit4ValueEdit.is_some() { update_entity.high_alarm_limit4_value_edit = Set(self.base.highAlarmLimit4ValueEdit.clone()); }
        if self.base.minimumScaleEdit.is_some() { update_entity.minimum_scale_edit = Set(self.base.minimumScaleEdit.clone()); }
        if self.base.maximunScaleEdit.is_some() { update_entity.maximun_scale_edit = Set(self.base.maximunScaleEdit.clone()); }

        return update_entity;
    }}

#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct CreatePointDto {
    #[serde(flatten)]
    pub base: BasePointDto,
}

#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct PointQuery {
    // name , description
    pub name: Option<String>,
    pub description: Option<String>,
}

impl PointQuery {
    pub(crate) fn from_json(p0: Value) -> Result<Self, serde_json::Error> {
        return serde_json::from_str(&p0.to_string());
    }
}

#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct TDSQLQuery {
    pub sql: String,
}

impl TDSQLQuery {
    pub(crate) fn from_json(p0: Value) -> Result<Self, serde_json::Error> {
        return serde_json::from_str(&p0.to_string());
    }
}

// [
// {
// "machineIndex": 1,
// "description": "",
// "sql": "select 1 as sort_order ,'dcs_rhte' as tablename,'undefined' as description ,'' as label ,'1' as borderType ,'undefined' as unit, last(ts) as ts ,last(pvalue) as pvalue from dcs_rhte  order by sort_order ;"
// }
// ]
#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct TDQuery {
    pub machineIndex: i32,
    pub description: String,
    pub sql: String,
    pub ret: Option<Vec<Value>>,
}

// public class InterpolationQueryParams
// {
// public List<string> TableNames { get; set; } = new List<string>();
// public string? StartTime { get; set; }
// public string? EndTime { get; set; }
// public string? Interval { get; set; }
// }
#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct InterpolationQueryParams {
    pub tableNames: Vec<String>,
    pub startTime: String,
    pub endTime: String,
    pub interval: String,
}

#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct InterpolationQueryResult {
    pub name: String,
    pub data: Vec<(i64, Option<f64>)>,
}

#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct PointAddVal {
    pub name: String,
    pub time: String,
    pub value: f64,
}
#[derive(Debug, Validate, Deserialize, Serialize, Clone)]
pub struct IdParam {
    pub id: i32,
}
